<template>
  <!-- 级联选择器 -->
  <el-cascader
    :options="cascaderList"
    ref="cascaderRef"
    v-model="vValue"
    :disabled="disabled"
    collapse-tags
    collapse-tags-tooltip
    :max-collapse-tags="maxCollapseTags"
    @blur="itemEvent('blur', $event)"
    @focus="itemEvent('focus', $event)"
    @change="handleChange"
    v-bind="attrs"
    clearable
  />
</template>

<script setup>
import _ from 'lodash';
import { vModelValue } from '@/utils/hooks.js';
import { apiMethods } from '@/utils/http.js';

const attrs = useAttrs();
const props = defineProps({
  modelValue: {
    type: [String, Array, Number],
  },
  options: {
    // 下拉值集合
    type: Array,
    default: () => [],
  },
  requestUrl: {
    // 下拉接口
    type: String,
    default: '',
  },
  tierData: {
    // 调用接口获取数据的层级关系
    type: String,
    default: '',
  },

  isInitData: {
    // 初始化是否加载数据
    type: Boolean,
    default: true,
  },
  // 传参
  params: {
    type: Object,
    default: () => ({}),
  },
  axiosMethod: {
    // 请求方式
    type: String,
    default: 'post',
  },
  cb: {
    // 获取列表之后回调
    type: Function,
  },
  // 子级单选 需要 props 中配合设置 multiple: true,checkStrictly: true
  onlySon: {
    type: Boolean,
    default: false,
  },
  maxCollapseTags: {
    type: Number,
    default: 1,
  },
});

/* props默认值
  {
    label: 'label',
    value: 'value',
    multiple: false,
    checkStrictly: false, // 是否父子不关联
    emitPath: true, // 值是否为数组
  }
*/

const emits = defineEmits(['update:modelValue', 'itemEvent']);
const { newValue: key } = vModelValue(props, emits);
let vValue = ref(key);
let cascaderRef = ref();

let requestList = ref([]);
let remoteParams = ref({});
let preSelectedGroupIds = ref([]);

onMounted(() => {
  if (props.isInitData && props.requestUrl) getDataList();
});

// 下拉值过滤
const cascaderList = computed(() => {
  let list = [];
  if (props.options?.length) {
    list = [...props.options];
  } else if (props.requestUrl) {
    list = requestList.value;
  }
  if (props.onlySon) {
    list = list.map(e => {
      e.disabled = true;
      return e;
    });
  }
  return list;
});

// 请求接口
async function getDataList(callback) {
  let res = await apiMethods[props.axiosMethod](props.requestUrl, {
    ...props.params,
    ...remoteParams.value,
  });
  requestList.value = [];
  let arr = null;
  if (props.tierData) {
    let tierArr = props.tierData.split('.');
    tierArr.forEach(item => {
      arr = arr ? arr[item] : res[item];
    });
  } else {
    arr = res.data.data || [];
  }
  requestList.value = arr;
  if (props.cb) {
    props.cb(arr);
  }
  if (callback) {
    callback();
  }
}

// 是否禁用
const disabled = computed(() => {
  return attrs.disabledFn && _.isFunction(attrs.disabledFn)
    ? attrs.disabledFn(attrs)
    : attrs.disabled || false;
});

function handleChange(data) {
  let result = null;
  let lableArr = cascaderRef.value.getCheckedNodes()[0]?.pathLabels;
  if (Array.isArray(lableArr)) {
    result = lableArr.join('/');
  }
  if (props.onlySon) {
    let newArr = JSON.parse(JSON.stringify(data));
    // 当前数组比之前的数组多
    if (newArr.length > preSelectedGroupIds.value.length) {
      let newOption = newArr[newArr.length - 1][0];
      // 查找当前数组中是否含有重复元素，有则删除第一个
      const index = newArr.findIndex(item => item[0] === newOption);
      if (index !== -1) {
        const filteredArr = newArr.filter(item => item[0] === newOption);
        if (filteredArr.length > 1) {
          newArr.splice(index, 1);
          // 保持当前根节点选中状态
          const lastElement = newArr.pop(); // 移除最后一个元素并保存
          newArr.unshift(lastElement); // 将最后一个元素插入到数组开头
        }
      }
    }
    preSelectedGroupIds.value = newArr;
    vValue.value = newArr;
    emits('itemEvent', { eventName: 'change', lableArr: newArr, result });
  } else {
    emits('itemEvent', { eventName: 'change', lableArr: data, result });
  }
}

// 事件
function itemEvent(eventName, $event, obj) {
  emits('itemEvent', {
    eventName,
    ...attrs,
    value: $event,
    prop: attrs.prop,
    ...obj,
  });
}

watch(
  () => props.requestUrl,
  url => {
    if (url) getDataList();
  }
);
</script>
